package com.wlps.exception;

import com.wlps.aspect.WebExceptionAspect;
import com.wlps.result.ResultUtils;
import com.wlps.result.ResultVo;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.stream.Collectors;

/**
 * <p>
 *
 * </p>
 *
 * @author ZWYZY
 * @since 2020/7/28
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
//    /**
//     * 未知的运行时异常拦截
//     */
//    @ExceptionHandler(RuntimeException.class)
////    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
//    @ResponseBody
//    public ResultVo notFount(RuntimeException e) {
//        log.error("运行时异常:", e);
//        return ResultUtils.error("服务器错误");
//    }

//    public void handler(JoinPoint joinPoint,Exception e){
//        String className = joinPoint.getTarget().getClass().getName();
//        String methodName = joinPoint.getSignature().getName();
//        Object[] args = joinPoint.getArgs();
//        logger.info("异常:" + e.getMessage());
//        logger.info("异常所在类：" + className);
//        logger.info("异常所在方法：" + methodName);
//        logger.info("异常中的参数：");
//        logger.info(methodName);
//        for (int i = 0; i < args.length; i++) {
//            logger.info(args[i].toString());
//        }
//    }
    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseBody
    public ResultVo MissingServletRequestParameterExceptionHandler(MissingServletRequestParameterException e){
        return ResultUtils.error("数据验证错误", 400);
    }

    @ExceptionHandler(DataIntegrityViolationException.class)
    @ResponseBody
    public ResultVo DataIntegrityViolationExceptionHandler(DataIntegrityViolationException e) {
//        String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining(","));
        return ResultUtils.error("数据验证错误", 400);
    }

    @ExceptionHandler(IllegalStateException.class)
    @ResponseBody
    public ResultVo IllegalStateExceptionHandler(IllegalStateException e){
        return ResultUtils.error("缺失必要的数据", 400);
    }

    /**
     * api异常处理返回json封装字符串对象
     *
     * @param
     * @return
     */
    @ExceptionHandler(value = ApiException.class)
    public ResultVo<Object> paramError(ApiException e) {
        return ResultUtils.error(e.getMessage(), e.getCode(), e.getData());
    }


    @ExceptionHandler(BindException.class)
    @ResponseBody
    public ResultVo bindExceptionHandler(BindException e) {
        String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining(","));
        return ResultUtils.error(message, 400);
    }

    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    @ResponseBody
    public ResultVo methodArgumentTypeMismatchExceptionHandler(MethodArgumentTypeMismatchException e) {
//        String message = e.getLocalizedMessage().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());
        return ResultUtils.error("数据输入格式错误", 400);
    }


    @ExceptionHandler({RuntimeException.class,NullPointerException.class})
    @ResponseBody
    public ResultVo runTimeExceptionHandler(RuntimeException e) {
//        String message = e.getLocalizedMessage().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());
            return ResultUtils.error(e.getMessage(), 400);
    }


    /**
     * 校验异常处理
     *
     * @param e
     * @return
     */
    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseBody
    public ResultVo constraintViolationExceptionHandler(ConstraintViolationException e) {
        String message = e.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining());
        return ResultUtils.error(message, 400);
    }

    @ExceptionHandler(NumberFormatException.class)
    @ResponseBody
    public ResultVo StringToNumber(ConstraintViolationException e) {
        String message = e.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining());
        return ResultUtils.error(message, 400);
    }
    /**
     * 校验异常处理
     *
     * @param e
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public ResultVo methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());
        return ResultUtils.error(message, 400);
    }

    @ExceptionHandler(HttpMessageNotReadableException.class)
    @ResponseBody
   public ResultVo HttpMessageNotReadableExceptionHandler(HttpMessageNotReadableException e){
//        return ResultUtils.error("不符合数据规范", 400);
        return ResultUtils.error(e.getMessage(), 400);

    }
}
